package com.financial.business.yspay.service.impl;

import com.financial.business.yspay.connector.YsBusinessFeign;
import com.financial.business.yspay.constants.FinancialPaymentYsEnumConstants;
import com.financial.business.yspay.dao.FinancialPaymentYsDao;
import com.financial.business.yspay.domain.FinancialPaymentYsDO;
import com.financial.business.yspay.dto.YsPaymentDTO;
import com.financial.business.yspay.service.FinancialPaymentYsService;
import com.financial.business.yspay.utils.JsonUtils;
import com.financial.business.yspay.utils.ValidateUtils;
import com.financial.business.yspay.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.rmi.transport.ObjectTable;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class FinancialPaymentYsServiceImpl implements FinancialPaymentYsService {
    public static final Logger logger = LoggerFactory.getLogger(FinancialSplitYsServiceImpl.class);

    @Autowired
    private FinancialPaymentYsDao financialPaymentYsDao;

    @Autowired
    private YsBusinessFeign ysBusinessFeign;

    @Override
    public FinancialPaymentYsDO get(Integer id) {
        return financialPaymentYsDao.get(id);
    }

    @Override
    public List<FinancialPaymentYsDO> list(Map<String, Object> map) {
        return financialPaymentYsDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return financialPaymentYsDao.count(map);
    }

    @Override
    public int save(FinancialPaymentYsDO financialPaymentYs) {
        return financialPaymentYsDao.save(financialPaymentYs);
    }

    @Override
    public int update(FinancialPaymentYsDO financialPaymentYs) {
        return financialPaymentYsDao.update(financialPaymentYs);
    }

    /**
     * 银盛代付
     *
     * @param requestParam
     * @return
     */
    @Override
    public ApiResult ysPayment(String requestParam) {
        logger.info("FinancialPaymentYsServiceImpl.ysPayment()------监听到平台内部代付完成json为：" + requestParam);
        YsPaymentDTO ysRefundDTO = JsonUtils.convertBean(requestParam, YsPaymentDTO.class);
        Map<String, Object> mapParams = JsonUtils.jsonToMap(requestParam);
        Object tempParams = mapParams.get("total_amount");
        /*分账退款金额*/
        String totalAmountStr = tempParams == null ? null : tempParams.toString();
        /*三方支付专用交易单号*/
        tempParams = mapParams.get("out_trade_no");
        String outTradeNo = tempParams == null ? null : tempParams.toString();
        /*对接平台商户号*/
        tempParams = mapParams.get("store_no");
        String storeNo = tempParams == null ? null : tempParams.toString();
        /*代付手续费*/
        tempParams = mapParams.get("payment_fee");
        String paymentFeeStr = tempParams == null ? null : tempParams.toString();
        /*提现类型*/
        tempParams = mapParams.get("payment_type");
        String paymentType = tempParams == null ? null : tempParams.toString();
        /*对接平台编码*/
        tempParams = mapParams.get("platform_no");
        String platformNo = tempParams == null ? null : tempParams.toString();
        /*对接平台代付单号*/
        tempParams = mapParams.get("payment_no");
        String paymentNo = tempParams == null ? null : tempParams.toString();
        /*订单说明*/
        tempParams = mapParams.get("subject");
        String subject = tempParams == null ? null : tempParams.toString();
        /*银行名称*/
        tempParams = mapParams.get("bank_name");
        String bankName = tempParams == null ? null : tempParams.toString();
        /*开户行所在城市*/
        tempParams = mapParams.get("bank_city");
        String bankCity = tempParams == null ? null : tempParams.toString();
        /*银行帐号*/
        tempParams = mapParams.get("bank_account_no");
        String bankAccountNo = tempParams == null ? null : tempParams.toString();
        /*银行帐号用户名*/
        tempParams = mapParams.get("bank_account_name");
        String bankAccountName = tempParams == null ? null : tempParams.toString();
        /*收款方银行账户类型 corporate :对公账户;personal:对私账户*/
        tempParams = mapParams.get("bank_account_type");
        String bankAccountType = tempParams == null ? null : tempParams.toString();
        /*支持卡类型，此处必填debit:借记卡;credit:信用卡 unit:单位结算卡*/
        tempParams = mapParams.get("bank_card_type");
        String bankCardType = tempParams == null ? null : tempParams.toString();
        /*业务代码*/
        tempParams = mapParams.get("business_code");
        String businessCode = tempParams == null ? null : tempParams.toString();
        /*回执地址*/
        tempParams = mapParams.get("notify_url");
        String notifyUrl = tempParams == null ? null : tempParams.toString();
        if (StringUtils.isBlank(totalAmountStr) || StringUtils.isBlank(outTradeNo)
                || StringUtils.isBlank(subject) || StringUtils.isBlank(paymentFeeStr)
                || StringUtils.isBlank(paymentType) || StringUtils.isBlank(storeNo)
                || StringUtils.isBlank(bankName) || StringUtils.isBlank(paymentNo)
                || StringUtils.isBlank(bankCity) || StringUtils.isBlank(bankAccountNo)
                || StringUtils.isBlank(platformNo) || StringUtils.isBlank(notifyUrl)
                || StringUtils.isBlank(businessCode) || StringUtils.isBlank(bankCardType)
                || StringUtils.isBlank(bankAccountType) || StringUtils.isBlank(bankAccountName)) {
            /*对所传字段进行非空校验判断*/
            logger.info("FinancialPaymentYsServiceImpl.ysPayment()------对所传字段有空值：" + ValidateUtils.validateProperty(ysRefundDTO));
            return ApiResult.failure(ValidateUtils.validateProperty(ysRefundDTO));
        }
        /*设定金额精度*/
        /*代付总金额*/
        BigDecimal totalAmount = new BigDecimal(totalAmountStr).setScale(2, RoundingMode.HALF_UP);
        /*代付手续费*/
        BigDecimal paymentFee = new BigDecimal(paymentFeeStr).setScale(2, RoundingMode.HALF_UP);
        try {
            /*代付之前数据库初始化*/
            FinancialPaymentYsDO financialPaymentYsDO = new FinancialPaymentYsDO();
            /*插入负数记录*/
            financialPaymentYsDO.setTotalAmount(totalAmount.multiply(new BigDecimal("-1")));
            /*组装调用银盛代付服务参数*/
            Map<String, Object> bizContentMap = new HashMap<>();
            /*根据订单号截取商户日期*/
            String shopdate = outTradeNo.substring(0, 8);
            bizContentMap.put("out_trade_no", outTradeNo);
            bizContentMap.put("business_code", businessCode);
            bizContentMap.put("currency", "CNY");
            bizContentMap.put("total_amount", totalAmount);
            bizContentMap.put("subject", subject);
            bizContentMap.put("bank_name", bankName);
            bizContentMap.put("bank_city", bankCity);
            bizContentMap.put("bank_account_no", bankAccountNo);
            bizContentMap.put("bank_account_name", bankAccountName);
            bizContentMap.put("bank_account_type", bankAccountType);
            bizContentMap.put("bank_card_type", bankCardType);
            bizContentMap.put("shopdate", shopdate);
            /*将map装换成json调用银盛代付*/
            String bizContentJson = JsonUtils.toJSon(bizContentMap);
            logger.info("FinancialPaymentYsServiceImpl.ysPayment()------调用银盛代付之前组装json为:" + bizContentJson);
            /*通过订单号查询库数据*/
            FinancialPaymentYsDO financialPaymentYsDOInfo = financialPaymentYsDao.getOne(outTradeNo);
            logger.info("FinancialPaymentYsServiceImpl.ysPayment()------通过订单号查询库数据信息,订单号:{}", outTradeNo);
            int res = 0;
            if (financialPaymentYsDOInfo != null) {
                logger.info("FinancialPaymentYsServiceImpl.ysPayment()------通过订单号查询库数据信息存在，执行更新操作");
                Map<String,Object> dataParams=new HashMap<>();
                dataParams.put("gmtModified",new Date());
                dataParams.put("state",FinancialPaymentYsEnumConstants.ENUM_STATE_WAIT);
                dataParams.put("outTradeNo",outTradeNo);
                dataParams.put("returnMessage",FinancialPaymentYsEnumConstants.ENUM_RETURN_MESSAGE);
                BigDecimal totalAmountData = financialPaymentYsDOInfo.getTotalAmount();
                logger.info("FinancialPaymentYsServiceImpl.ysPayment()------通过订单号查询库数据,订单号信息为:{},代付金额为:{}", outTradeNo, totalAmountData);
                String state = financialPaymentYsDOInfo.getState();
                logger.info("FinancialPaymentYsServiceImpl.ysPayment()------通过订单号查询库数据,订单号信息为:{},代付状态为:{}", outTradeNo, state);
                if (totalAmountData.compareTo(totalAmount) != 0) {
                    logger.info("FinancialPaymentYsServiceImpl.ysPayment()------历史订单号代付金额与当前退款金额不符");
                    return ApiResult.failure("历史订单号代付金额与当前代付金额不符");
                }
                if (state.equals("1")) {
                    logger.info("FinancialPaymentYsServiceImpl.ysPayment()------历史订单号代付状态成功");
                    return ApiResult.success("该订单历史代付成功");
                } else {
                    logger.info("FinancialPaymentYsServiceImpl.ysPayment()------历史订单号代付状态不成功或者未发起");
                    res = financialPaymentYsDao.updateInfo(dataParams);
                }
            } else {
                logger.info("FinancialPaymentYsServiceImpl.ysPayment()------通过订单号查询库数据信息存在，执行保存操作");
                financialPaymentYsDO.setGmtCreate(new Date());
                financialPaymentYsDO.setIsDelete(FinancialPaymentYsEnumConstants.ENUM_ISDELETE_UNDEL);
                financialPaymentYsDO.setOutTradeNo(outTradeNo);
                financialPaymentYsDO.setPaymentFee(paymentFee);
                financialPaymentYsDO.setPaymentNo(paymentNo);
                financialPaymentYsDO.setPlatformNo(platformNo);
                financialPaymentYsDO.setResqContent(requestParam);
                financialPaymentYsDO.setState(FinancialPaymentYsEnumConstants.ENUM_STATE_WAIT);
                financialPaymentYsDO.setReturnMessage(FinancialPaymentYsEnumConstants.ENUM_RETURN_MESSAGE);
                financialPaymentYsDO.setStoreNo(storeNo);
                /*将初始化返回值落库*/
                financialPaymentYsDO.setReturnMessage(bizContentJson);
                res = financialPaymentYsDao.save(financialPaymentYsDO);

            }
            if (res > 0) {
                ApiResult paymentApi = ysBusinessFeign.payment(bizContentJson);
                logger.info("FinancialPaymentYsServiceImpl.ysPayment()------调用银盛代付返回为:" + paymentApi);
                /*对返回的参数判断进行落库处理*/
                String returnMsg = (String) paymentApi.getResult();
                /*更改数据库状态*/
                Map<String, Object> condMap = new HashMap<>();
                condMap.put("outTradeNo", outTradeNo);
                condMap.put("returnMessage", returnMsg);
                condMap.put("gmtModified", new Date());
                if (paymentApi.getCode() == FinancialPaymentYsEnumConstants.ENUM_RETURN_CODE && (returnMsg != null && returnMsg != "")) {
                    condMap.put("state", FinancialPaymentYsEnumConstants.ENUM_STATE_SUC);
                    int updateState = financialPaymentYsDao.updateInfo(condMap);
                    if (updateState > 0) {
                        logger.info("FinancialPaymentYsServiceImpl.ysPayment()------代付同步回执信息更改状态成功！");
                        return ApiResult.success(returnMsg);
                    }
                } else {
                    condMap.put("state", FinancialPaymentYsEnumConstants.ENUM_STATE_FAIL);
                    financialPaymentYsDao.updateInfo(condMap);
                    logger.info("FinancialPaymentYsServiceImpl.ysPayment()------代付同步回执信息有误！" + paymentApi);
                    return ApiResult.failure(paymentApi);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("FinancialPaymentYsServiceImpl.ysPayment()------代付同步回执信息有误！" + e.getMessage());
        }
        return ApiResult.failure(requestParam);
    }

    /**
     * 查询银盛代付一条记录
     *
     * @param condMap
     * @return
     */
    @Override
    public String query(Map<String, Object> condMap) {
        return financialPaymentYsDao.query(condMap);
    }

}
